IoT Core ルールのSQLで名前にハイフン「-」があるJSONを参照するときは、get()関数を使いましょうという話
IoT Coreのルール(SQL)で名前にハイフン-
を含むJSONの参照に失敗しました。
地味にハマる部分でもあり、気づくまで時間がかかる事もあるため、初めからget()
を使うと良さそうです。
扱うJSONデータの例
下記のJSONデータとします。
{ "id": "123", "bbb": "this is sample.", "hoge": { "xxx-yyy": true } }
IoT ルール実行が失敗するとき
JSONデータのxxx-yyy
がtrue
のときだけ、アクションが実行されるように設定しますが、このSQLを使ってもルールアクションは実行されません。
SELECT * FROM '/topic/sample' WHERE hoge.xxx-yyy = true
get()を使って参照する
IoT ルールを設定する
ルールクエリ(SQL)
get()
を用いてJSONデータのxxx-yyy
がtrue
のときだけ、アクションが実行されるようにします。
SELECT * FROM '/topic/sample' WHERE get(hoge, 'xxx-yyy') = true
ちなみに、最上位階層にある場合は、get(*, 'xxx-yyy')
で参照できます。
アクション
DynamoDBv2
を用いて、DynamoDBテーブルにデータを格納します。
DynamoDBテーブルは、ハッシュキーがid(str)
になっています。
トピックにデータをPublishする
IoT Coreのテスト画面でPublishします。
- トピック:
/topic/sample
- JSONデータ:下記
{ "id": "123", "bbb": "this is sample.", "hoge": { "xxx-yyy": true } }
動作結果
無事にIoTルールが実行され、DynamoDBテーブルにデータが格納されました。
さいごに
多くのプログラミング言語では変数名にハイフン-
が使えません。おそらく演算子のマイナス-
と区別できないからだと思います。
今にして思えば「確かに……」という感想ですが、地味にハマります。
初めからget()
を使うと良さそうですね。
ASCII 範囲 (U+0001..U+007F) 内では、識別子として有効な文字は Python 2.x におけるものと同じです。 大文字と小文字の A から Z、アンダースコア _、先頭の文字を除く数字 0 から 9 です。
https://docs.python.org/ja/3/reference/lexical_analysis.html#identifiers